package sc.digital.human;

import okhttp3.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Objects;

public class Text2Audio extends JFrame implements ActionListener, Callback {
    JSpinner spd, pit, vol;
    JComboBox<Tsn.Per> per;
    JComboBox<Tsn.Aue> aue;
    JTextArea tex;
    JButton tts;
    Setup setup = new Setup(this);
    Token token = new Token();
    OkHttpClient httpClient = new OkHttpClient.Builder().build();

    public Text2Audio() {
        super.setTitle("语音合成");
        super.setIconImage(Config.LOGO);
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        super.setLayout(new BorderLayout());
        super.add(new JToolBar() {{
            this.setLayout(new FlowLayout(FlowLayout.LEFT));
            this.add(new JLabel("语速"));
            this.add(spd = new JSpinner(new SpinnerNumberModel(5, 0, 15, 1)));
            this.add(new JLabel("音调"));
            this.add(pit = new JSpinner(new SpinnerNumberModel(5, 0, 15, 1)));
            this.add(new JLabel("音量"));
            this.add(vol = new JSpinner(new SpinnerNumberModel(5, 0, 15, 1)));
            this.add(new JLabel("音库"));
            this.add(per = new JComboBox<>(Tsn.Per.values()));
            this.add(new JLabel("格式"));
            this.add(aue = new JComboBox<>(Tsn.Aue.values()));
        }}, BorderLayout.NORTH);
        super.add(new JScrollPane(tex = new JTextArea(10, 0) {{
            this.setLineWrap(true);
            this.setWrapStyleWord(true);
        }}), BorderLayout.CENTER);
        super.add(new JPanel() {{
            this.setLayout(new BorderLayout());
            this.add(new JButton("设置") {{
                this.setFocusable(false);
                this.setFocusPainted(false);
                this.addActionListener((e) -> setup.setVisible(true));
            }}, BorderLayout.WEST);
            this.add(tts = new JButton("合成") {{
                this.setFocusable(false);
                this.setFocusPainted(false);
                this.addActionListener(Text2Audio.this);
            }}, BorderLayout.CENTER);
        }}, BorderLayout.SOUTH);
        super.pack();
        super.setLocationRelativeTo(null);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        this.tts.setEnabled(false);
        if (this.tex.getText().trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "文本不能为空！", "", JOptionPane.PLAIN_MESSAGE);
            this.tts.setEnabled(true);
            return;
        }
        this.token.refresh((credentials) -> {
            if (credentials == null) {
                JOptionPane.showMessageDialog(this, "鉴权认证失败！", "", JOptionPane.PLAIN_MESSAGE);
                this.tts.setEnabled(true);
                return;
            }
            this.httpClient.newCall(new Request.Builder().url(HttpUrl.parse("https://tsn.baidu.com/text2audio").newBuilder()
                    .addQueryParameter("tex", tex.getText())
                    .addQueryParameter("tok", credentials.access_token)
                    .addQueryParameter("cuid", "SC1234567890")
                    .addQueryParameter("ctp", "1")
                    .addQueryParameter("lan", "zh")
                    .addQueryParameter("spd", spd.getValue().toString())
                    .addQueryParameter("pit", pit.getValue().toString())
                    .addQueryParameter("vol", vol.getValue().toString())
                    .addQueryParameter("per", ((Tsn.Per) Objects.requireNonNull(per.getSelectedItem())).key)
                    .addQueryParameter("aue", ((Tsn.Aue) Objects.requireNonNull(aue.getSelectedItem())).key)
                    .build()).build()).enqueue(this);
        });
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (!response.isSuccessful() || response.body() == null) {
            JOptionPane.showMessageDialog(this, response.code(), response.message(), JOptionPane.PLAIN_MESSAGE);
        } else {
            if (!Objects.requireNonNull(response.header("Content-Type")).startsWith("audio/")) {
                JOptionPane.showMessageDialog(this, response.body().string(), "", JOptionPane.PLAIN_MESSAGE);
            } else {
                JFileChooser chooser = new JFileChooser();
                if (JFileChooser.APPROVE_OPTION == chooser.showSaveDialog(this)) {
                    File file = chooser.getSelectedFile();
                    String ext = response.header("Content-Type").replace("audio/", "");
                    String name = String.format("%s.%s", file.getName(), ext.length() > 3 ? "pcm" : ext);
                    Files.write(new File(file.getParentFile(), name).toPath(), response.body().bytes());
                }
                JOptionPane.showMessageDialog(this, "合成完成！", "", JOptionPane.PLAIN_MESSAGE);
            }
        }
        this.tts.setEnabled(true);
    }

    @Override
    public void onFailure(Call call, IOException e) {
        JOptionPane.showMessageDialog(this, e.toString(), e.getMessage(), JOptionPane.PLAIN_MESSAGE);
        this.tts.setEnabled(true);
    }


    public static void main(String[] args) throws Exception {
        Config.readConfig();
        Config.readCmdlineArgs(args);
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(() -> new Text2Audio().setVisible(true));
    }
}
